package com.yss.reportworld.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.spring.PropertyPreFilters;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.yss.common.core.constant.RequestDataHelper;
import com.yss.common.core.domain.TreeNode;
import com.yss.common.core.enums.YssStatusEnum;
import com.yss.common.core.exception.BusinessException;
import com.yss.common.core.exception.base.BaseException;
import com.yss.common.core.utils.StringUtils;
import com.yss.common.core.utils.uuid.IdUtils;
import com.yss.common.security.utils.SecurityUtils;
import com.yss.reportworld.domain.DataModular;
import com.yss.reportworld.domain.Report;
import com.yss.reportworld.mapper.DataModularMapper;
import com.yss.reportworld.util.TableInfoUtil;
import lombok.extern.slf4j.Slf4j;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.yss.reportworld.service.IModularService;
import com.yss.reportworld.mapper.ModularMapper;
import com.yss.reportworld.domain.Modular;

/**
 * 模块Service业务层处理
 *
 * @author yss
 * @date 2023-03-17
 */
@Slf4j
@Service
public class ModularServiceImpl extends ServiceImpl<ModularMapper, Modular> implements IModularService {
    @Autowired
    private DataModularMapper dataModularMapper;

    /**
     * 查询模块列表
     *
     * @param modular 模块
     * @return 模块
     */
    @Override
    public List<Modular> selectModularList(Modular modular) {
        try {
            TableInfoUtil.handleTableVersion(modular.getHisVersion()); // 替换表名
            QueryWrapper<Modular> wrapper = new QueryWrapper();
            wrapper.orderByDesc("STATUS");
            wrapper.orderByAsc("PARENT_ID,ORDER_NUM");
            if (StringUtils.isNotEmpty(modular.getName())) {
                wrapper.like("NAME", modular.getName());
            }
            if (StringUtils.isNotEmpty(modular.getVersion())) {
                wrapper.eq("VERSION", modular.getVersion());
            }
            if (null != modular.getStatus()) {
                wrapper.eq("STATUS", modular.getStatus());
            }
            return this.list(wrapper);
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
    }

    /**
     * 查询模块信息
     *
     * @param modular
     * @return
     */
    public Modular selectModularById(Modular modular) {
        try {
            TableInfoUtil.handleTableVersion(modular.getHisVersion()); // 替换表名
            return this.getById(modular.getId());
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
    }

    /**
     * 查询模块树结构信息
     *
     * @return 模块树信息集合
     */
    public List<TreeNode> selectModularTreeList() {
        List<TreeNode> list = new ArrayList<>();
        QueryWrapper<Modular> wrapper = new QueryWrapper<>();
        wrapper.orderByAsc("PARENT_ID,ORDER_NUM");
        wrapper.eq("STATUS", YssStatusEnum.NORMAL.getCode());
        List<Modular> listModular = this.list(wrapper);
        if (StringUtils.isEmpty(listModular)) {
            return list;
        }
        List<String> tempList = listModular.stream().map(Modular::getId).collect(Collectors.toList());
        Set<String> set = new HashSet<>();
        for (Modular modular : listModular) {
            if (set.contains(modular.getParentId()) || tempList.contains(modular.getParentId())) {
                continue;
            }
            list.addAll(this.recursionTree(modular.getParentId(), listModular));
            set.add(modular.getParentId());
        }
        return list;
    }

    private List<TreeNode> recursionTree(String id, List<Modular> listModular) {
        List<TreeNode> list = new ArrayList<>();
        for (Modular modular : listModular) {
            if (!id.equals(modular.getParentId())) {
                continue;
            }
            TreeNode treeNode = this.handModularToNode(modular);
            List<TreeNode> children = recursionTree(modular.getId(), listModular);
            treeNode.setChildren(children);
            list.add(treeNode);
        }
        return list;
    }

    /**
     * 将业务功能转化成TreeNode
     */
    private TreeNode handModularToNode(Modular modular) {
        TreeNode node = new TreeNode();
        node.setId(modular.getId());
        node.setParentId(modular.getParentId());
        node.setLabel(modular.getName());
        return node;
    }


    /**
     * 递归查询所有下级模块ID集合
     *
     * @param id
     * @return
     * @throws Exception
     */
    public List<String> queryModularIds(String id) {
        if (StringUtils.isBlank(id)) {
            throw new BusinessException("获取模块信息失败，请稍后重试！");
        }
        List<String> strList = new ArrayList<>();
        List<Modular> list = this.list(new QueryWrapper<>());
        recursionIds(id, strList, list);
        return strList;
    }

    private void recursionIds(String id, List<String> strList, List<Modular> list) {
        for (Modular modular : list) {
            if (!id.equals(modular.getParentId())) {
                continue;
            }
            strList.add(modular.getId());
            recursionIds(modular.getId(), strList, list);
        }
    }

    /**
     * 添加模块信息
     *
     * @param modular
     * @throws Exception
     */
    public boolean addModular(Modular modular) {
        try {
            if (StringUtils.isNull(modular)) {
                throw new BusinessException("获取模块信息失败，请稍后重试！");
            }
            TableInfoUtil.handleTableVersion(modular.getHisVersion()); // 替换表名
            String id = IdUtils.fastSimpleUUID();
            modular.setId(id);
            modular.setCreateBy(SecurityUtils.getUsername());
            modular.setCreateTime(new Date());
            if ("0".equals(modular.getParentId())) {
                return this.save(modular);
            }
            //添加之前没有下级模块的数据的 添加了以后 模块的关联关系修改到下级
            // 获取该模块的上级之前是不是最明细的
            QueryWrapper<Modular> wrapper = new QueryWrapper<>();
            wrapper.eq("PARENT_ID", modular.getParentId());
            List<Modular> list = this.list(wrapper);
            if (StringUtils.isEmpty(list)) { //添加的上级以前没有下级
                // 将关联关系表中原来模块的数据，更新成现在这个新的下级菜单
                UpdateWrapper<DataModular> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("MODULAR_ID", modular.getParentId());
                DataModular dataModular = new DataModular();
                dataModular.setModularId(id);
                dataModularMapper.update(dataModular, updateWrapper);
            }
            return this.save(modular);
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
    }

    /**
     * 修改模块信息
     *
     * @param modular
     * @throws Exception
     */
    public boolean editModular(Modular modular) {
        try {
            if (StringUtils.isNull(modular) || StringUtils.isBlank(modular.getId())) {
                throw new BusinessException("获取模块信息失败，请稍后重试！");
            }
            TableInfoUtil.handleTableVersion(modular.getHisVersion()); // 替换表名
            // 修改之前的上级只有一个下级
            Modular oldModular = this.getById(modular.getId());
            QueryWrapper<Modular> wrapperOld = new QueryWrapper<>();
            wrapperOld.eq("PARENT_ID", oldModular.getId());
            List<Modular> listOld = this.list(wrapperOld);
            if (StringUtils.isEmpty(listOld)) { //修改之前没有下级
                QueryWrapper<Modular> wrapper = new QueryWrapper<>();
                wrapper.eq("PARENT_ID", oldModular.getParentId());
                List<Modular> list = this.list(wrapper);
                if (!StringUtils.isEmpty(list) && list.size() == 1) {
                    // 原来的关联表是这个明细的ID 更新成现在将会变成明细的上级ID
                    UpdateWrapper<DataModular> updateWrapper = new UpdateWrapper<>();
                    updateWrapper.eq("MODULAR_ID", oldModular.getId());
                    DataModular dataModular = new DataModular();
                    dataModular.setModularId(oldModular.getParentId());
                    dataModularMapper.update(dataModular, updateWrapper);
                }
            }
            modular.setUpdateTime(new Date());
            modular.setUpdateBy(SecurityUtils.getUsername());
            //修改后的上级
            if ("0".equals(modular.getParentId())) {
                return this.updateById(modular);
            }
            // 修改后的这上级 之前是否存在下级
            QueryWrapper<Modular> wrapper = new QueryWrapper<>();
            wrapper.eq("PARENT_ID", modular.getParentId());
            List<Modular> list = this.list(wrapper);
            if (StringUtils.isEmpty(list)) { //添加的上级以前没有下级
                // 将关联关系表中原来模块的数据，更新成现在这个新的下级菜单
                UpdateWrapper<DataModular> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("MODULAR_ID", modular.getParentId());
                DataModular dataModular = new DataModular();
                dataModular.setModularId(modular.getId());
                dataModularMapper.update(dataModular, updateWrapper);
            }
            return this.updateById(modular);
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
    }

    /**
     * 删除模块信息
     *
     * @param modular
     * @throws Exception
     */
    public boolean delModular(Modular modular) {
        try {
            if (StringUtils.isBlank(modular.getId())) {
                throw new BusinessException("获取删除模块信息失败，请稍后重试！");
            }
            TableInfoUtil.handleTableVersion(modular.getHisVersion()); // 替换表名
            QueryWrapper<Modular> modularQueryWrapper1 = new QueryWrapper<>();
            modularQueryWrapper1.eq("PARENT_ID", modular.getId());
            List<Modular> list = this.list(modularQueryWrapper1);
            if (list.size() > 0) {
                throw new BusinessException("存在下级模块,不允许删除");
            }
            // List<String> list = this.queryModularIds(id); //所有下级模块
            Modular oldModular = this.getById(modular.getId());
            // 删除的这个ID 不是一个一级的
            if ("0".equals(oldModular.getParentId())) {
                // 删除关联关系表中所所有改id包括所有下级的
                QueryWrapper<DataModular> wrapper = new QueryWrapper<>();
                wrapper.in("MODULAR_ID", modular.getId());
                dataModularMapper.delete(wrapper);
                return this.removeById(modular.getId());
            }
            UpdateWrapper<DataModular> updateWrapper = new UpdateWrapper<>();
            updateWrapper.in("MODULAR_ID", modular.getId());
            DataModular dataModular = new DataModular();
            dataModular.setModularId(oldModular.getParentId());
            dataModularMapper.update(dataModular, updateWrapper);
            return this.removeById(modular.getId());
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
    }

    /**
     * 里获取报表模块信息
     *
     * @return
     * @throws Exception
     */
    public Map<String, Modular> getModularMap() {
        Map<String, Modular> mapReportModular = new HashMap<>();
        QueryWrapper<Modular> wrapper = new QueryWrapper<>();
        wrapper.orderByAsc("NAME");
        List<Modular> listModular = this.list(wrapper);
        if (StringUtils.isEmpty(listModular)) {
            return null;
        }
        for (Modular modular : listModular) {
            if (StringUtils.isNull(modular) || StringUtils.isBlank(modular.getId())) {
                continue;
            }
            mapReportModular.put(modular.getId(), modular);
        }
        return mapReportModular;
    }

    /**
     * 模块数据的json
     */
    public String getModularJsonInfo() {
        String[] includeProperties = {"id", "parentId", "name", "status"};
        PropertyPreFilters filters = new PropertyPreFilters();
        PropertyPreFilters.MySimplePropertyPreFilter includefilter = filters.addFilter();
        includefilter.addIncludes(includeProperties);
        QueryWrapper<Modular> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("STATUS", YssStatusEnum.getUpgradeToolsZipStatus());
        queryWrapper.orderByAsc("NAME");
        List<Modular> list = this.list(queryWrapper);
        return JSONObject.toJSONString(list, includefilter, SerializerFeature.WriteMapNullValue);
    }


    /**
     * 校验模块名称是否唯一
     *
     * @param modular
     * @return 结果
     */
    @Override
    public boolean checkNameUnique(Modular modular) {
        try {
            TableInfoUtil.handleTableVersion(modular.getHisVersion()); // 替换表名
            String modularId = StringUtils.isNull(modular.getId()) ? "-1" : modular.getId();
            QueryWrapper<Modular> wrapper = new QueryWrapper<>();
            wrapper.eq("NAME", modular.getName());
            wrapper.eq("PARENT_ID", modular.getParentId());
            Modular info = this.getOne(wrapper);
            if (StringUtils.isNotNull(info) && !info.getId().equals(modularId)) {
                return false;
            }
            return true;
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
    }
}
